package com.edu.exam.entity.curriculum.questionbank;

import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.hibernate.annotations.Comment;
import org.springframework.data.annotation.CreatedDate;
import org.springframework.data.jpa.domain.support.AuditingEntityListener;

import jakarta.persistence.*;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotNull;
import jakarta.validation.constraints.Size;
import java.math.BigDecimal;
import java.time.LocalDateTime;

/**
 * 填空题评分规则实体类
 * 所属模块：B-02 题库管理模块
 * 对应数据库表：fill_grading_rule
 *
 * 填空题评分规则实体类
 *
 * @author System
 * @version 1.0.0
 */
@Entity
@Table(name = "fill_grading_rule")
@Comment("填空题评分规则表")
@EntityListeners(AuditingEntityListener.class)
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class FillGradingRule {

    /**
     * 主键ID
     */
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "id")
    private Long id;

    /**
     * 规则唯一标识符
     */
    @NotBlank(message = "规则ID不能为空")
    @Size(max = 50, message = "规则ID长度不能超过50个字符")
    @Column(name = "rule_id", nullable = false, length = 50, unique = true)
    private String ruleId;

    /**
     * 关联的填空题ID
     */
    @NotBlank(message = "题目ID不能为空")
    @Column(name = "question_id", nullable = false)
    private String questionId;

    /**
     * 规则名称
     */
    @NotBlank(message = "规则名称不能为空")
    @Size(max = 100, message = "规则名称长度不能超过100个字符")
    @Column(name = "rule_name", nullable = false, length = 100)
    private String ruleName;

    /**
     * 规则类型（PRIMARY-主要规则，BACKUP-备用规则，TEMPORARY-临时规则，SPECIAL-特殊规则）
     */
    @NotBlank(message = "规则类型不能为空")
    @Size(max = 30, message = "规则类型长度不能超过30个字符")
    @Column(name = "rule_type", nullable = false, length = 30)
    private String ruleType;

    /**
     * 评分模式（ALL_OR_NOTHING-全有或全无，PARTIAL_SCORE-部分得分，WEIGHTED_SCORE-权重得分，STEP_SCORE-阶梯得分）
     */
    @NotBlank(message = "评分模式不能为空")
    @Size(max = 30, message = "评分模式长度不能超过30个字符")
    @Column(name = "grading_mode", nullable = false, length = 30)
    private String gradingMode;

    /**
     * 是否为主要规则
     */
    @NotNull(message = "主要规则标识不能为空")
    @Column(name = "is_primary", nullable = false)
    private Boolean isPrimary;

    /**
     * 是否启用
     */
    @NotNull(message = "启用状态不能为空")
    @Column(name = "is_active", nullable = false)
    private Boolean isActive;

    /**
     * 是否允许部分得分
     */
    @NotNull(message = "部分得分设置不能为空")
    @Column(name = "partial_score_enabled", nullable = false)
    private Boolean partialScoreEnabled;

    /**
     * 总分
     */
    @NotNull(message = "总分不能为空")
    @Column(name = "total_score", nullable = false, precision = 8, scale = 2)
    private BigDecimal totalScore;

    /**
     * 每空基础分数
     */
    @Column(name = "score_per_blank", precision = 6, scale = 2)
    private BigDecimal scorePerBlank;

    /**
     * 部分得分阈值（0-1之间，低于此值得0分，高于此值得部分分数）
     */
    @Column(name = "partial_score_threshold", precision = 3, scale = 2)
    private BigDecimal partialScoreThreshold;

    /**
     * 部分得分比例（0-1之间，匹配度乘以此比例得到得分）
     */
    @Column(name = "partial_score_ratio", precision = 3, scale = 2)
    private BigDecimal partialScoreRatio;

    /**
     * 容错是否启用
     */
    @NotNull(message = "容错设置不能为空")
    @Column(name = "tolerance_enabled", nullable = false)
    private Boolean toleranceEnabled;

    /**
     * 容错类型（SPELLING-拼写错误，WHITESPACE-空格错误，PUNCTUATION-标点错误，CASE-大小写错误）
     */
    @Column(name = "tolerance_types", length = 100)
    private String toleranceTypes;

    /**
     * 最大容错数
     */
    @Column(name = "max_tolerance_count")
    private Integer maxToleranceCount;

    /**
     * 每个错误的扣分
     */
    @Column(name = "penalty_per_error", precision = 6, scale = 2)
    private BigDecimal penaltyPerError;

    /**
     * 是否启用倒扣分
     */
    @NotNull(message = "倒扣分设置不能为空")
    @Column(name = "negative_score_enabled", nullable = false)
    private Boolean negativeScoreEnabled;

    /**
     * 倒扣分模式（FIXED-固定扣分，PROPORTIONAL-比例扣分，GRADUAL-阶梯扣分）
     */
    @Size(max = 20, message = "倒扣分模式长度不能超过20个字符")
    @Column(name = "negative_score_mode", length = 20)
    private String negativeScoreMode;

    /**
     * 倒扣分值
     */
    @Column(name = "negative_score_value", precision = 6, scale = 2)
    private BigDecimal negativeScoreValue;

    /**
     * 最低得分（倒扣分后的最低分数）
     */
    @Column(name = "minimum_score", precision = 6, scale = 2)
    private BigDecimal minimumScore;

    /**
     * 是否启用时间奖励
     */
    @NotNull(message = "时间奖励设置不能为空")
    @Column(name = "time_bonus_enabled", nullable = false)
    private Boolean timeBonusEnabled;

    /**
     * 时间奖励类型（EARLY-提前完成奖励，FAST-快速完成奖励）
     */
    @Size(max = 20, message = "时间奖励类型长度不能超过20个字符")
    @Column(name = "time_bonus_type", length = 20)
    private String timeBonusType;

    /**
     * 时间奖励阈值（秒）
     */
    @Column(name = "time_bonus_threshold_seconds")
    private Integer timeBonusThresholdSeconds;

    /**
     * 时间奖励分数
     */
    @Column(name = "time_bonus_score", precision = 6, scale = 2)
    private BigDecimal timeBonusScore;

    /**
     * 是否启用准确率奖励
     */
    @NotNull(message = "准确率奖励设置不能为空")
    @Column(name = "accuracy_bonus_enabled", nullable = false)
    private Boolean accuracyBonusEnabled;

    /**
     * 准确率奖励阈值
     */
    @Column(name = "accuracy_bonus_threshold", precision = 3, scale = 2)
    private BigDecimal accuracyBonusThreshold;

    /**
     * 准确率奖励分数
     */
    @Column(name = "accuracy_bonus_score", precision = 6, scale = 2)
    private BigDecimal accuracyBonusScore;

    /**
     * 阶梯得分配置（JSON格式）
     */
    @Column(name = "step_score_config", columnDefinition = "TEXT")
    private String stepScoreConfig;

    /**
     * 权重配置（JSON格式，每个空的权重）
     */
    @Column(name = "weight_config", columnDefinition = "TEXT")
    private String weightConfig;

    /**
     * 自定义评分逻辑（JSON格式）
     */
    @Column(name = "custom_grading_logic", columnDefinition = "TEXT")
    private String customGradingLogic;

    /**
     * 适用难度范围（JSON格式）
     */
    @Column(name = "difficulty_range", columnDefinition = "TEXT")
    private String difficultyRange;

    /**
     * 适用科目类型
     */
    @Size(max = 50, message = "适用科目类型长度不能超过50个字符")
    @Column(name = "applicable_subject_type", length = 50)
    private String applicableSubjectType;

    /**
     * 适用年级
     */
    @Size(max = 50, message = "适用年级长度不能超过50个字符")
    @Column(name = "applicable_grade", length = 50)
    private String applicableGrade;

    /**
     * 生效时间
     */
    @Column(name = "effective_time")
    private LocalDateTime effectiveTime;

    /**
     * 失效时间
     */
    @Column(name = "expiry_time")
    private LocalDateTime expiryTime;

    /**
     * 规则描述
     */
    @Column(name = "rule_description", columnDefinition = "TEXT")
    private String ruleDescription;

    /**
     * 规则说明
     */
    @Column(name = "rule_instructions", columnDefinition = "TEXT")
    private String ruleInstructions;

    /**
     * 示例评分（JSON格式）
     */
    @Column(name = "example_scoring", columnDefinition = "TEXT")
    private String exampleScoring;

    /**
     * 规则版本
     */
    @NotNull(message = "规则版本不能为空")
    @Column(name = "rule_version", nullable = false)
    private Integer ruleVersion;

    /**
     * 创建者ID
     */
    @Size(max = 50, message = "创建者ID长度不能超过50个字符")
    @Column(name = "created_by", nullable = false, length = 50)
    private String createdBy;

    /**
     * 创建时间
     */
    @CreatedDate
    @Column(name = "create_time", nullable = false, updatable = false)
    private LocalDateTime createTime;

    /**
     * 更新人ID
     */
    @Size(max = 50, message = "更新人ID长度不能超过50个字符")
    @Column(name = "updated_by", nullable = false, length = 50)
    private String updatedBy;

    /**
     * 更新时间
     */
    @Column(name = "update_time", nullable = false)
    private LocalDateTime updateTime;

    /**
     * 审核人ID
     */
    @Size(max = 50, message = "审核人ID长度不能超过50个字符")
    @Column(name = "reviewer_id", length = 50)
    private String reviewerId;

    /**
     * 审核时间
     */
    @Column(name = "review_time")
    private LocalDateTime reviewTime;

    /**
     * 使用次数
     */
    @Column(name = "usage_count")
    private Integer usageCount;

    /**
     * 软删除标识
     */
    @NotNull(message = "软删除标识不能为空")
    @Column(name = "is_deleted", nullable = false)
    private Boolean isDeleted;

    /**
     * 删除时间
     */
    @Column(name = "delete_time")
    private LocalDateTime deleteTime;

}